/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-12-07     LOJAM       the first version
 */

#include <rtthread.h>
#include <rtdevice.h>
#include "board.h"
#include "multi_button.h"
#include "wavplayer.h"
#include "ble_smarthome.h"


#define BUTTON_PIN_0 rt_pin_get("PF.0")
#define BUTTON_PIN_1 rt_pin_get("PF.1")
#define LED_PIN      rt_pin_get("PE.1")
#define LOCK_PIN     rt_pin_get("PE.4")
#define LED_ON()     rt_pin_write(LED_PIN, PIN_LOW)
#define LED_OFF()    rt_pin_write(LED_PIN, PIN_HIGH)
#define LOCK_ON()    rt_pin_write(LOCK_PIN, PIN_LOW)
#define LOCK_OFF()   rt_pin_write(LOCK_PIN, PIN_HIGH)
#define NUM_OF_SONGS (2u)
static struct button btn_0;
static struct button btn_1;
static uint32_t cnt_0 = 0;
static uint32_t cnt_1 = 0;

static char *table[3] = { "lighton.wav", "lightoff.wav", "lock.wav", };
static uint8_t smrthm_sta_buf[20]={0};

void saia_channels_set(uint8_t channels);
void saia_volume_set(rt_uint8_t volume);
uint8_t saia_volume_get(void);

static int smrthm_gpio_init(void)
{
    LED_OFF();
    LOCK_OFF();
    rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LOCK_PIN, PIN_MODE_OUTPUT);

    return RT_EOK;
}

INIT_BOARD_EXPORT(smrthm_gpio_init);

static void light_ctrl(void)
{
    if(smrthm_sta_buf[0])
    {
        LED_ON();
        rt_kprintf("Lighting on!\n");
        wavplayer_play(table[0]);
    }
    else
    {
        LED_OFF();
        wavplayer_play(table[1]);
        rt_kprintf("Lighting off!\n");
    }
}


static void lock_ctrl(void)
{
    if(smrthm_sta_buf[1])
    {
        LOCK_ON();
        rt_thread_mdelay(1000);
        rt_kprintf("Lock open successe!\n");
        wavplayer_play(table[2]);
        LOCK_OFF();
        smrthm_sta_buf[1] = 0;
    }
}

static uint8_t button_read_pin_0(void)
{
    return rt_pin_read(BUTTON_PIN_0);
}

static uint8_t button_read_pin_1(void)
{
    return rt_pin_read(BUTTON_PIN_1);
}

static void button_0_callback(void *btn)
{
    uint32_t btn_event_val;
    btn_event_val = get_button_event((struct button *) btn);
    switch (btn_event_val)
    {
    case SINGLE_CLICK:
        smrthm_sta_buf[0] = !smrthm_sta_buf[0];
        light_ctrl();

        break;

    case DOUBLE_CLICK:
        if (cnt_0 == 1)
        {
            saia_channels_set(1);
        }
        else
        {
            saia_channels_set(2);
            cnt_0 = 0;
        }
        cnt_0++;
        rt_kprintf("button 0 double click\n");
        break;

    case LONG_PRESS_START:
        if (cnt_0 == 1)
        {
            saia_volume_set(30);
        }
        else if (cnt_0 == 2)
        {
            saia_volume_set(50);
        }
        else
        {
            saia_volume_set(100);
            cnt_0 = 0;
        }
        cnt_0++;
        rt_kprintf("vol=%d\n", saia_volume_get());

        rt_kprintf("button 0 long press start\n");
        break;

    case LONG_PRESS_HOLD:
        rt_kprintf("button 0 long press hold\n");
        break;
    }
}


static void button_1_callback(void *btn)
{
    uint32_t btn_event_val;
    btn_event_val = get_button_event((struct button *) btn);
    switch (btn_event_val)
    {
    case SINGLE_CLICK:
//        wavplayer_play(table[(cnt_1++) % NUM_OF_SONGS]);
        rt_kprintf("button 1 single click\n");
        smrthm_sta_buf[1] = 1;
        lock_ctrl();
        break;

    case DOUBLE_CLICK:
        rt_kprintf("button 1 double click\n");
        break;

    case LONG_PRESS_START:
        rt_kprintf("button 1 long press start\n");
        break;

    case LONG_PRESS_HOLD:
        rt_kprintf("button 1 long press hold\n");
        break;
    }
}

static void btn_thread_entry(void* p)
{
    while (1)
    {
        /* 5ms */
        rt_thread_delay(RT_TICK_PER_SECOND / 200);
        button_ticks();
    }
}

static int multi_button_test(void)
{
    rt_thread_t thread = RT_NULL;
    /* Create background ticks thread */
    thread = rt_thread_create("btn", btn_thread_entry, RT_NULL, 1024, 10, 10);
    if (thread == RT_NULL)
    {
        return RT_ERROR;
    }
    rt_thread_startup(thread);

    /* low level drive */
    rt_pin_mode(BUTTON_PIN_0, PIN_MODE_INPUT_PULLUP);
    button_init(&btn_0, button_read_pin_0, PIN_LOW);
    button_attach(&btn_0, SINGLE_CLICK, button_0_callback);
    button_attach(&btn_0, DOUBLE_CLICK, button_0_callback);
    button_attach(&btn_0, LONG_PRESS_START, button_0_callback);
    button_attach(&btn_0, LONG_PRESS_HOLD, button_0_callback);
    button_start(&btn_0);

    rt_pin_mode(BUTTON_PIN_1, PIN_MODE_INPUT_PULLUP);
    button_init(&btn_1, button_read_pin_1, PIN_LOW);
    button_attach(&btn_1, SINGLE_CLICK, button_1_callback);
    button_attach(&btn_1, DOUBLE_CLICK, button_1_callback);
    button_attach(&btn_1, LONG_PRESS_START, button_1_callback);
    button_attach(&btn_1, LONG_PRESS_HOLD, button_1_callback);
    button_start(&btn_1);

    return RT_EOK;
}

INIT_APP_EXPORT(multi_button_test);

void gatt_smrthm_srv_event_handle(event_id_t event_id, void *buf)
{
    uint8_t lastLightSta;

    lastLightSta = smrthm_sta_buf[0];

    switch (event_id)
    {
    case status_read_event_id:
        memcpy(buf, smrthm_sta_buf, 2);
        break;

    case ctrl_write_event_id:
        memcpy(smrthm_sta_buf, buf, 2);
        if(lastLightSta != smrthm_sta_buf[0])
        {
            light_ctrl();
        }
        lock_ctrl();
        break;

    default:
        break;
    }

}


static int gatt_smrthm_srv_event_init(void)
{
    reg_gatt_event_handle(gatt_smrthm_srv_event_handle);
}

INIT_APP_EXPORT(gatt_smrthm_srv_event_init);
